SK006 DAKO RTU on AutostainerLink48 PD-L1 IHC 22C3 pharmDx for Autostainer (SK006): https://www.agilent.com/en/product/pharmdx/pd-l1-ihc-22c3-pharmdx/pd-l1-ihc-22c3-pharmdx-for-autostainer-link-48-1760224
See notes: https://pdl1.azurewebsites.net Tilsinbreastcancer.org
This is the same antibody as used in the KEYNOTE-355 study (Pembrolizumab plus chemotherapy versus placebo plus chemotherapy for previously untreated locally recurrent inoperable or metastatic triple-negative breast cancer)
In the KEYNOTE_355 trial, a survival benefit of recieving pembrolizumab is shown for mTNBC with CPS score >=10. CPS = Combined Positive Score.
CPS score = (Positive Tumor cells + positive immune cells / Total number of tumor cells) * 100
Immune cells = lymphocytes and macrophages.
This gives a CPS score that theoretically can be more than 100.
A minimum of 100 viable tumor cells in the PD-L1–stained slide is required for the specimen to be considered adequate for PD-L1 evaluation.
37% of TNBC has CPS >= 10 in the KEYNOTE_355 trial.
CPS calculation:
positiveImmuneCells = 851
positiveTumorCells = 1005
negativeTumorCells = 21219
(TumorCells = positiveTumorCells+negativeTumorCells)## [1] 22224
(CPS = ((positiveImmuneCells+positiveTumorCells)/TumorCells)*100)## [1] 8.351332
From the QuPath paper:
Analysis of PD-L1 IHC The approach to scoring PD-L1 was similar to p53, apart from the following: 1) a three-way random trees classifier was trained to distinguish between epithelial, non-epithelial and ‘other’ detections (including artefacts and necrosis); 2) cells were classified as positive or negative based upon a single intensity threshold applied to the maximum DAB optical density within the full cell area, and 3) summary scores were generated as the percentage of cells classified as positive, with ‘other’ detections removed.
Analysis of p53 IHC Preprocessing steps were applied as described above. QuPath’s Cell detection command was then used to identify cells across all cores based upon nuclear staining. This command additionally estimates the full extent of each cell based upon a constrained expansion of the nucleus region, and calculates up to 33 measurements of intensity and morphology, including nucleus area, circularity, staining intensity for hematoxylin and DAB, and nucleus/cell area ratio. Because not all of these measurements are expected to provide independent or useful information with regard to cell classification, a subset of 16 measurements was chosen empirically and supplemented for each cell by measuring the local density of cells, and taking a Gaussian-weighted sum of the corresponding measurements within neighboring cells using QuPath’s Add smoothed features command. A two-way random trees classifier was then interactively trained to distinguish tumor epithelial cells from all other detections (comprising non-epithelial cells, necrosis, or any artefacts misidentified as cells) and applied across all slides (see Supplementary Video 2). Intensity thresholds were set to further subclassify tumor cells as being negative, weak, moderate or strongly positive for p53 staining based upon mean nuclear DAB optical densities. An H-score was calculated for each tissue core by adding 3x% strongly stained tumor nuclei, 2x% moderately stained tumor nuclei, and 1x% weakly stained tumor nuclei32, giving results in the range 0 (all tumor nuclei negative) to 300 (all tumor nuclei strongly positive).
Import 18 randomly selected images from PETREMAC arms A, B, E, F, G, H.
Estimate Stain vector for each protein staining.
Estimate stain vector
Image used for stain vector: 2022-08-06 15.37.15.ndpi
Create Script “PDL1_EstimateStainVector.groovey”
setImageType('BRIGHTFIELD_H_DAB');
setColorDeconvolutionStains('{"Name" : "H-DAB-PDL1", "Stain 1" :
"Hematoxylin", "Values 1" : "0.77475 0.55533 0.30229", "Stain 2" :
"DAB", "Values 2" : "0.20981 0.43913 0.87358", "Background" : " 232 233
233 "}');Shortcut for Script editor: Command+L, search for script.
Select appropriate settings for positive cell detection.
PD-L1 stains the membrane. There is no current reliable/easy method for
selecting membrane staining in QuPath, so the most practical method is
to set the max intensity for the cell as threshold for positive cell
detection.
– Intensity threshold parameters > Score compartment > Cell: DAB OD max
Select an appropriate threshold that balances detection of false positives and false negatives among the samples in the training set with the selected stain vector.
Tested positive cell detection on negative slides, positive slides and slides with artefacts. Standard settings, Score compartment Cell: DAB OD max single threshold 0.45 seemed the most reasonable balance of picking up weak positive, and false positives from background. Worked well with strong staining too.
Cell detection standard settings, Cell: DAB OD max. Intensity threshold was set as 0.45.
Positive Cell detection settings
Go to workflow, and save as a script.
Run positive cell detection and save script from workflow as “PositiveCellDetectionPDL1.groovey”
runPlugin('qupath.imagej.detect.cells.PositiveCellDetection', '{"detectionImageBrightfield": "Hematoxylin OD", "requestedPixelSizeMicrons": 0.5, "backgroundRadiusMicrons": 8.0, "medianRadiusMicrons": 0.0, "sigmaMicrons": 1.5, "minAreaMicrons": 10.0, "maxAreaMicrons": 500.0, "threshold": 0.1, "maxBackground": 2.0, "watershedPostProcess": true, "excludeDAB": false, "cellExpansionMicrons": 5.0, "includeNuclei": true, "smoothBoundaries": true, "makeMeasurements": true, "thresholdCompartment": "Cell: DAB OD max", "thresholdPositive1": 0.45, "thresholdPositive2": 0.4, "thresholdPositive3": 0.6000000000000001, "singleThreshold": true}');QuPath splits the annotated area into tiles to not overload memory,
and runs the cell detection tile by tile for larger areas:
This gives us a lot of measurements, which can be found by clicking the Measurement table icon. The Nucleus/Cell area ratio gives a good pinpoint to whether each cell is a tumor cell or not (Size and density), but all other measurements are also taken into account when classifying cells.
Add smooth to cell detection: -> Analyze -> Calculate features -> Add smooth features
In “Smooth object features” window select Radius (FWHM) = 50 um, and do not tick the box “Smooth within class”.
From the QuPath docs:
The weighting depends on distance, i.e. cells that are further away have less contribution to the result. Technically, distance is based on centroids and the weighting is calculated from a Gaussian function, where the parameter required in the dialog box is the full-width-at-half-maximum of the Gaussian function. Less technically, putting higher numbers into the dialog box results in more smoothing. This reduces the noisiness of the measurements more effectively, but also makes it more difficult to distinguish smaller areas containing particular cell types.
This will supplement all the measurements with the weighted sum of the corresponding measurements of the neighbouring cells, smooth out all the measurements Although tumor cells will correspond well with the Nucleus/cell area, no single measurement is good enough, so we will rely on machine learning to classify the detected cells into “Tumor” (Epithelial like) and “Stroma” .
Smooth features
In short: Smooth features to help classification algorithm.
Run as script in script editor:
runPlugin('qupath.lib.plugins.objects.SmoothFeaturesPlugin', {"fwhmMicrons": 50.0, "smoothWithinClasses": false}');Note; Issue with samples with weak nuclear blue staining, cell detection does not detect all cells.
Add Tumor/Stroma/immune cell annotation
Use brush-tool or wand/polygon tool to annotate an area - Control-click -> Set class
Annotate Tumor/Immune/ignore
Repeat for all images in PDL1_train project.
Add - Tumor - Immune cell - Ignore (Red blood cells, debree, necrosis, artefacts etc) annotations.
Open the Train Object Classifier with live update. Select all images in project for training. Do a manual check for correct annotations, and add more where needed
-> Classify -> Object classification -> Train object classifier Live update Object filter : Detections (all) Classifier : Random trees (RTrees) Classes : All classes Training : Unlocked annotations
Save classifier when satisfied, and load classifier in stead of train when classifying images in a new project.
Saved classifier as “PDL1_TumorImmuneIgnore_cellClassifier.json” in the project folder:
-> classifiers -> object_classifiers
A PD-L1 negative tumor:
A PD-L1 positive tumor:
Note on artefacts: